package com.xiezc;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import lombok.Data;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;

/**
 * @author wb-xzc291800
 * @date 2018/09/05 14:44
 */
@Slf4j
public class RecvService {

    private RecvService(DatagramChannel channel) {
        super();
        this.channel = channel;
    }

    static RecvService recvService;

    private BlockingQueue<RecvObj> recvBuf = new LinkedBlockingQueue<>();

    final DatagramChannel channel;

    @Synchronized
    public static RecvService single(DatagramChannel channel) {
        if (recvService == null) {
            recvService = new RecvService(channel);
        }
        log.info("RecvService 收包服务初始化完成... ");
        return recvService;
    }

    public RecvObj poll() {
        return recvBuf.poll();
    }

    public RecvObj poll(long time, TimeUnit timeUnit) throws InterruptedException {
        return recvBuf.poll(time, timeUnit);
    }

    public RecvObj take() throws InterruptedException {
        return recvBuf.take();
    }

    public void start() {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    ByteBuffer byteBuffer = ByteBuffer.allocate(900);
                    InetSocketAddress socketAddress = (InetSocketAddress)channel.receive(byteBuffer);
                    byteBuffer.flip();
                    RecvObj recvObj = new RecvObj();
                    recvObj.setByteBuffer(byteBuffer);
                    recvObj.setInetSocketAddress(socketAddress);
                    boolean add = recvBuf.add(recvObj);

                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }, "");

        thread.setDaemon(true);
        thread.start();
    }
}

@Data
class RecvObj {

    ByteBuffer byteBuffer;

    InetSocketAddress inetSocketAddress;

}